Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement division and modulo for RV32I #134

Merged
merged 1 commit into from
Jun 22, 2024
Merged

Conversation

DrXiao
Copy link
Collaborator

@DrXiao DrXiao commented Jun 20, 2024

This commit allows shecc to generate a sequence of instructions to perform division or modulo for RISC-V targets with RV32I only.

Close #46

@DrXiao DrXiao changed the title Implenment division and modulo for RV32I Implement division and modulo for RV32I Jun 20, 2024
@jserv jserv requested review from nosba0957 and vacantron June 20, 2024 19:49
Copy link
Collaborator

@jserv jserv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code generator for division and modulo has only 2 instructions in difference.

--- codegen-div.c
+++ codegen-mod.c
@@ -7,7 +7,7 @@
             emit(__srai(__t1, __t3, 31));
             emit(__add(__t3, __t3, __t1));
             emit(__xor(__t3, __t3, __t1));
-            emit(__xor(__t5, __t0, __t1));
+            emit(__addi(__t5, __t0, 0));
             /* Unsigned integer division */
             emit(__addi(__t0, __zero, 0));
             emit(__addi(__t1, __zero, 1));
@@ -23,7 +23,7 @@
             emit(__srli(__t1, __t1, 1));
             emit(__srli(__t3, __t3, 1));
             emit(__bne(__t1, __zero, -20));
-            emit(__addi(rd, __t0, 0));
-            /* Handle the correct sign for the quotient */
+            emit(__addi(rd, __t2, 0));
+            /* Handle the correct sign for the remainder */
             emit(__beq(__t5, __zero, 8));
             emit(__sub(rd, __zero, rd));

Thus, we can introduce a helper function to generate div/mod emulation instructions, enhancing code reusability.

@jserv
Copy link
Collaborator

jserv commented Jun 20, 2024

Thus, we can introduce a helper function to generate div/mod emulation instructions, enhancing code reusability.

A similar case for div/mod emulation instruction generation exists in the Arm backend. Let's refine the RISC-V backend in this pull request and address the Arm backend in another.

@DrXiao
Copy link
Collaborator Author

DrXiao commented Jun 21, 2024

Yes, the proposed changes can be improved to enhance code reusability. I will refine the RISC-V backend first and submit another pull request for refining the Arm backend.

@DrXiao
Copy link
Collaborator Author

DrXiao commented Jun 21, 2024

Rather than adding a helper function, I thought of another approach that adds two local variables in emit_ph2_ir() and uses if statements to achieve reusability.

src/riscv-codegen.c Outdated Show resolved Hide resolved
/* Prepare the variables to reuse the same code for
* the instruction sequence of division and modulo.
*/
rv_reg soft_div_rd = __t0, soft_div_rs2_sign_reg = __t1;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

soft_div_rs2_sign_reg looks weird. Can you shorten it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about renaming it as divisor_mask_reg?

At the beginning of the emulation, it obtains the absolute values of the dividend and divisor using the following approach.

int32_t abs(int32_t x) 
{
    int32_t mask = x >> 31;       /* arithmetic right shift */
    return (x + mask) ^ mask
}

Therefore, the register __t1 will store 0 or 0xFFFFFFFF initially, indicating that it serves as the mask for the divisor.
(Similarly, __t0 will be the mask for the dividend.)

If the requested operation is division, divisor_mask_reg will be __t1 and helps to determine the result's sign. Otherwise, for the modulo operation, because it only needs the dividend's mask to determine the result's sign, divisor_mask_reg becomes unnecessary and is assigned to __zero so that it doesn't affect the result's sign.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simply name it divisor_mask as it is intended to behave as its name suggests.

src/riscv-codegen.c Outdated Show resolved Hide resolved
Copy link
Collaborator

@jserv jserv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Execute git rebase -i to squash the commits.

This commit allows shecc to generate a sequence of
instructions to perform division or modulo for RISC-V
targets with RV32I only.

Close sysprog21#46
@DrXiao DrXiao requested a review from jserv June 22, 2024 04:52
@jserv jserv merged commit 6cdd7e2 into sysprog21:master Jun 22, 2024
4 checks passed
@jserv
Copy link
Collaborator

jserv commented Jun 22, 2024

Thank @DrXiao for contributing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support Arm/RISC-V targets without integer division instructions
2 participants